/*******************************************************************************
* Copyright (C) 2018, Huada Semiconductor Co.,Ltd All rights reserved.
*
* This software is owned and published by:
* Huada Semiconductor Co.,Ltd ("HDSC").
*
* BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
* BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
*
* This software contains source code for use with HDSC
* components. This software is licensed by HDSC to be adapted only
* for use in systems utilizing HDSC components. HDSC shall not be
* responsible for misuse or illegal use of this software for devices not
* supported herein. HDSC is providing this software "AS IS" and will
* not be responsible for issues arising from incorrect user implementation
* of the software.
*
* Disclaimer: 
* HDSC MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
* REGARDING THE SOFTWARE (INCLUDING ANY ACOOMPANYING WRITTEN MATERIALS),
* ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING,
* WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED
* WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED
* WARRANTY OF NONINFRINGEMENT.
* HDSC SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT,
* NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT
* LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION,
* LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR
* INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA,
* SAVINGS OR PROFITS,
* EVEN IF Disclaimer HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
* INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED
* FROM, THE SOFTWARE.
*
* This software may be replicated in part or whole for the licensed use,
* with the restriction that this Disclaimer and Copyright notice must be
* included with each copy of this software, whether used in part or whole,
* at all times.
*/
/******************************************************************************/
/** \file sysctrl.h
 **
 ** Headerfile for SYSCTRL functions
 ** @link SYSCTRL Group Some description @endlink 
 **
 ** History:
 **   - 2018-04-15   Lux	 First Version
 **
 ******************************************************************************/

#ifndef __SYSCTRL_H__
#define __SYSCTRL_H__

/*******************************************************************************
 * Include files
 ******************************************************************************/
#include "ddl.h"


#ifdef __cplusplus
extern "C"
{
#endif

/**
 ******************************************************************************
 ** \defgroup SysCtrlGroup (SYSCTRL)
  **
 ******************************************************************************/
//@{

/**
 *******************************************************************************
 ** function prototypes.
 ******************************************************************************/

/******************************************************************************
 * Global type definitions
 ******************************************************************************/
 
/**
 *******************************************************************************
 ** \brief 系统时钟输入源类型定义
 ** \note
 ******************************************************************************/
typedef enum en_sysctrl_clk_source
{
	SysctrlClkRCH  = 0u,			   ///< 内部高速时钟
	SysctrlClkXTH  = 1u,			   ///< 外部高速时钟
	SysctrlClkRCL  = 2u,			   ///< 内部低速时钟
	SysctrlClkXTL  = 3u,			   ///< 外部低速时钟
	SysctrlClkPLL  = 4u,			   ///< PLL时钟
}en_sysctrl_clk_source_t;

/**
 *******************************************************************************
 ** \brief RCH频率值枚举类型定义
 ******************************************************************************/
typedef enum en_sysctrl_rch_freq
{
	SysctrlRchFreq4MHz	 = 4u,			   ///< 4MHz
	SysctrlRchFreq8MHz	 = 3u,			   ///< 8MHz
	SysctrlRchFreq16MHz	= 2u,			   ///< 16MHz
	SysctrlRchFreq22_12MHz = 1u,			   ///< 22.12MHz
	SysctrlRchFreq24MHz	= 0u,			   ///< 24MHz
}en_sysctrl_rch_freq_t;

/**
 *******************************************************************************
 ** \brief XTAL驱动能力类型定义
 ******************************************************************************/
typedef enum en_sysctrl_xtal_driver
{
	SysctrlXtalDriver0 = 0u,				///< 最弱驱动能力
	SysctrlXtalDriver1 = 1u,				///< 弱驱动能力
	SysctrlXtalDriver2 = 2u,				///< 一般驱动能力
	SysctrlXtalDriver3 = 3u,				///< 最强驱动能力
}en_sysctrl_xtal_driver_t;

/**
 *******************************************************************************
 ** \brief XTH频率值范围选择类型定义
 ******************************************************************************/
typedef enum en_sysctrl_xth_freq
{
	SysctrlXthFreq4_8MHz   = 0u,				///< 4~8MHz
	SysctrlXthFreq8_16MHz  = 1u,				///< 8~16MHz
	SysctrlXthFreq16_24MHz = 2u,				///< 16~24MHz
	SysctrlXthFreq24_32MHz = 3u,				///< 24~32MHz
}en_sysctrl_xth_freq_t;

/**
 *******************************************************************************
 ** \brief XTH时钟稳定周期数类型定义
 ******************************************************************************/
typedef enum en_sysctrl_xth_cycle
{
	SysctrlXthStableCycle256   = 0u,			  ///< 256 个周期数
	SysctrlXthStableCycle1024  = 1u,			  ///< 1024 个周期数
	SysctrlXthStableCycle4096  = 2u,			  ///< 4096 个周期数
	SysctrlXthStableCycle16384 = 3u,			  ///< 16384 个周期数
}en_sysctrl_xth_cycle_t;

/**
 *******************************************************************************
 ** \brief RCL频率值枚举类型定义
 ******************************************************************************/
typedef enum en_sysctrl_rcl_freq
{
	SysctrlRclFreq32768	= 0x11u,			   ///< 32.768KHz
	SysctrlRclFreq38400	= 0x10u,			   ///< 38.4KHz
}en_sysctrl_rcl_freq_t;

/**
 *******************************************************************************
 ** \brief RCL时钟稳定周期数类型定义
 ******************************************************************************/
typedef enum en_sysctrl_rcl_cycle
{
	SysctrlRclStableCycle4   = 0u,				  ///< 4 个周期数
	SysctrlRclStableCycle16  = 1u,				  ///< 16 个周期数
	SysctrlRclStableCycle64  = 2u,				  ///< 64 个周期数
	SysctrlRclStableCycle256 = 3u,				  ///< 256 个周期数
}en_sysctrl_rcl_cycle_t;

/**
 *******************************************************************************
 ** \brief XTL时钟稳定周期数类型定义
 ******************************************************************************/
typedef enum en_sysctrl_xtl_cycle
{
	SysctrlXtlStableCycle256   = 0u,				  ///< 256 个周期数
	SysctrlXtlStableCycle1024  = 1u,				  ///< 1024 个周期数
	SysctrlXtlStableCycle4096  = 2u,				  ///< 4096 个周期数
	SysctrlXtlStableCycle16384 = 3u,				  ///< 16384 个周期数
}en_sysctrl_xtl_cycle_t;

/**
 *******************************************************************************
 ** \brief XTL晶体振幅枚举类型定义
 ******************************************************************************/
typedef enum en_sysctrl_xtl_amp
{
	SysctrlXtlAmp0 = 0u,				///< 最小振幅
	SysctrlXtlAmp1 = 1u,				///< 小振幅
	SysctrlXtlAmp2 = 2u,				///< 一般振幅
	SysctrlXtlAmp3 = 3u,				///< 最大振幅
}en_sysctrl_xtl_amp_t;

/**
 *******************************************************************************
 ** \brief PLL时钟稳定周期数类型定义
 ******************************************************************************/
typedef enum en_sysctrl_pll_cycle
{
	SysctrlPllStableCycle128   = 0u,				  ///< 128个周期数
	SysctrlPllStableCycle256   = 1u,				  ///< 256个周期数
	SysctrlPllStableCycle512   = 2u,				  ///< 512个周期数
	SysctrlPllStableCycle1024  = 3u,				  ///< 1024个周期数
	SysctrlPllStableCycle2048  = 4u,				  ///< 2048个周期数
	SysctrlPllStableCycle4096  = 5u,				  ///< 4096个周期数
	SysctrlPllStableCycle8192  = 6u,				  ///< 8192个周期数
	SysctrlPllStableCycle16384 = 7u,				  ///< 16384个周期数	
}en_sysctrl_pll_cycle_t;

/**
 *******************************************************************************
 ** \brief PLL输入频率范围类型定义
 ******************************************************************************/
typedef enum en_sysctrl_pll_infreq
{
	SysctrlPllInFreq4_6MHz   = 0u,				  ///< 4~16MHz
	SysctrlPllInFreq6_12MHz  = 1u,				  ///< 6~12MHz
	SysctrlPllInFreq12_20MHz = 2u,				  ///< 12~20MHz
	SysctrlPllInFreq20_24MHz = 3u,				  ///< 20~24MHz  
}en_sysctrl_pll_infreq_t;

/**
 *******************************************************************************
 ** \brief PLL输出频率范围类型定义
 ******************************************************************************/
typedef enum en_sysctrl_pll_outfreq
{
	SysctrlPllOutFreq8_12MHz  = 0u,				 ///< 8~12MHz
	SysctrlPllOutFreq12_18MHz = 1u,				 ///< 12~18MHz
	SysctrlPllOutFreq18_24MHz = 2u,				 ///< 18~24MHz
	SysctrlPllOutFreq24_36MHz = 3u,				 ///< 24~36MHz
	SysctrlPllOutFreq36_48MHz = 4u,				 ///< 36~48MHz
}en_sysctrl_pll_outfreq_t;

/**
 *******************************************************************************
 ** \brief PLL输入时钟源类型定义
 ******************************************************************************/
typedef enum en_sysctrl_pll_clksource
{
	SysctrlPllXthXtal   = 0u,				  ///< XTH晶振输入的时钟
	SysctrlPllXthIn	 = 2u,				  ///< XTH从端口输入的时钟
	SysctrlPllRch	   = 3u,				  ///< RCH时钟
}en_sysctrl_pll_clksource_t;

/**
 *******************************************************************************
 ** \brief PLL输入时钟源类型定义
 ******************************************************************************/
typedef enum en_sysctrl_pll_mul
{
	SysctrlPllMul2  = 2u,				   ///< 2倍频
	SysctrlPllMul3  = 3u,				   ///< 3倍频
	SysctrlPllMul4  = 4u,				   ///< 4倍频
	SysctrlPllMul5  = 5u,				   ///< 5倍频
	SysctrlPllMul6  = 6u,				   ///< 6倍频
	SysctrlPllMul7  = 7u,				   ///< 7倍频
	SysctrlPllMul8  = 8u,				   ///< 8倍频
	SysctrlPllMul9  = 9u,				   ///< 9倍频
	SysctrlPllMul10 = 10u,				  ///< 10倍频
	SysctrlPllMul11 = 11u,				  ///< 11倍频
	SysctrlPllMul12 = 12u,				  ///< 12倍频
}en_sysctrl_pll_mul_t;

/**
 *******************************************************************************
 ** \brief HCLK时钟分频系数类型定义
 ******************************************************************************/
typedef enum en_sysctrl_hclk_div
{
	SysctrlHclkDiv1   = 0u,			  ///< SystemClk
	SysctrlHclkDiv2   = 1u,			  ///< SystemClk/2
	SysctrlHclkDiv4   = 2u,			  ///< SystemClk/4
	SysctrlHclkDiv8   = 3u,			  ///< SystemClk/8
	SysctrlHclkDiv16  = 4u,			  ///< SystemClk/16
	SysctrlHclkDiv32  = 5u,			  ///< SystemClk/32
	SysctrlHclkDiv64  = 6u,			  ///< SystemClk/64
	SysctrlHclkDiv128 = 7u,			  ///< SystemClk/128
}en_sysctrl_hclk_div_t;

/**
 *******************************************************************************
 ** \brief PCLK分频系数
 ******************************************************************************/
typedef enum en_sysctrl_pclk_div
{
	SysctrlPclkDiv1 = 0u,				///< HCLK
	SysctrlPclkDiv2 = 1u,				///< HCLK/2
	SysctrlPclkDiv4 = 2u,				///< HCLK/4
	SysctrlPclkDiv8 = 3u,				///< HCLK/8
}en_sysctrl_pclk_div_t;

/**
 *******************************************************************************
 ** \brief RTC高速时钟补偿时钟频率数据类型定义
 ******************************************************************************/
typedef enum en_sysctrl_rtc_adjust
{
	SysctrlRTC4MHz  = 0u,				///< 4MHz
	SysctrlRTC6MHz  = 1u,				///< 6MHz
	SysctrlRTC8MHz  = 2u,				///< 8MHz
	SysctrlRTC12MHz = 3u,				///< 12MHz
	SysctrlRTC16MHz = 4u,				///< 16MHz
	SysctrlRTC20MHz = 5u,				///< 20MHz
	SysctrlRTC24MHz = 6u,				///< 24MHz
	SysctrlRTC32MHz = 7u,				///< 32MHz
}en_sysctrl_rtc_adjust_t;

/**
 *******************************************************************************
 ** \brief 系统控制模块其他功能数据类型定义
 ******************************************************************************/
typedef enum en_sysctrl_func
{
	SysctrlEXTHEn		   = 1u,					///< 使能外部高速时钟从输入引脚输入
	SysctrlEXTLEn		   = 2u,					///< 使能外部低速速时钟从输入引脚输入
	SysctrlXTLAlwaysOnEn	= 3u,					///< 使能后XTL_EN只可置位
	SysctrlClkFuncRTCLpmEn  = 5u,					///< 使能RTC低功耗模式
	SysctrlCMLockUpEn	   = 6u,					///< 使能后CPU执行无效指令会复位MCU
	SysctrlSWDUseIOEn	   = 8u,					///< SWD端口设为IO功能
}en_sysctrl_func_t;

/**
 *******************************************************************************
 ** \brief 外设时钟门控开关类型枚举
 ******************************************************************************/
typedef enum en_sysctrl_peripheral_gate
{
	SysctrlPeripheralUart0	  = 0u,	   ///< 串口0
	SysctrlPeripheralUart1	  = 1u,	   ///< 串口1
	SysctrlPeripheralLpUart0	= 2u,	   ///< 低功耗串口0
	SysctrlPeripheralLpUart1	= 3u,	   ///< 低功耗串口1
	SysctrlPeripheralI2c0	   = 4u,	   ///< I2C0
	SysctrlPeripheralI2c1	   = 5u,	   ///< I2C1
	SysctrlPeripheralSpi0	   = 6u,	   ///< SPI0
	SysctrlPeripheralSpi1	   = 7u,	   ///< SPI1
	SysctrlPeripheralBaseTim	= 8u,	   ///< 基础定时器TIM0/1/2
	SysctrlPeripheralLpTim0	 = 9u,	   ///< 低功耗定时器0
	SysctrlPeripheralAdvTim	 = 10u,	  ///< 高级定时器TIM4/5/6
	SysctrlPeripheralTim3	   = 11u,	  ///< 定时器3
	SysctrlPeripheralOpa		= 13u,	  ///< OPA
	SysctrlPeripheralPca		= 14u,	  ///< 可编程计数阵列
	SysctrlPeripheralWdt		= 15u,	  ///< 看门狗
	SysctrlPeripheralAdcBgr	 = 16u,	  ///< ADC&BGR
	SysctrlPeripheralVcLvd	  = 17u,	  ///< VC和LVD
	SysctrlPeripheralRng		= 18u,	  ///< RNG
	SysctrlPeripheralPcnt	   = 19u,	  ///< PCNT
	SysctrlPeripheralRtc		= 20u,	  ///< RTC
	SysctrlPeripheralTrim	   = 21u,	  ///< 时钟校准
	SysctrlPeripheralLcd		= 22u,	  ///< LCD
	SysctrlPeripheralTick	   = 24u,	  ///< 系统定时器
	SysctrlPeripheralSwd		= 25u,	  ///< SWD
	SysctrlPeripheralCrc		= 26u,	  ///< CRC
	SysctrlPeripheralAes		= 27u,	  ///< AES
	SysctrlPeripheralGpio	   = 28u,	  ///< GPIO
	SysctrlPeripheralDma		= 29u,	  ///< DMA
	SysctrlPeripheralFlash	  = 31u,	  ///< Flash
	SysctrlPeripheralDac		= 35u,	  ///< DAC
	SysctrlPeripheralLpTim1	 = 36u,	  ///< 低功耗定时器1
	SysctrlPeripheralUart2	  = 40u,	  ///< UART2
	SysctrlPeripheralUart3	  = 41u,	  ///< UART3	
}en_sysctrl_peripheral_gate_t;

/**
 *******************************************************************************
 ** \brief 时钟初始化配置结构体定义
 ******************************************************************************/
typedef struct
{
	en_sysctrl_clk_source_t  enClkSrc;	   ///< 时钟源选择
	en_sysctrl_hclk_div_t	enHClkDiv;	  ///< HCLK分频系数
	en_sysctrl_pclk_div_t	enPClkDiv;	  ///< PCLK分频系数
}stc_sysctrl_clk_cfg_t;

/**
 *******************************************************************************
 ** \brief 时钟初始化配置结构体定义
 ******************************************************************************/
typedef struct
{
	en_sysctrl_pll_infreq_t	enInFreq;		///< PLL输入时钟频率范围选择
	en_sysctrl_pll_outfreq_t   enOutFreq;	   ///< PLL输出时钟频率范围选择
	en_sysctrl_pll_clksource_t enPllClkSrc;	 ///< PLL输入时钟源选择
	en_sysctrl_pll_mul_t	   enPllMul;		///< PLL倍频系数选择
}stc_sysctrl_pll_cfg_t;

/******************************************************************************
 * Global variable declarations ('extern', definition in C source)
 ******************************************************************************/

/******************************************************************************
 * Global function prototypes (definition in C source)
 ******************************************************************************/
///< 系统时钟初始化API:用于上电后，系统工作之前对主频及外设时钟进行初始化； 
///< 注意1：使用该初始化函数前需要根据系统，必须优先设置目标内部时钟源的TRIM值或外部时钟源的频率范围，
///< 注意2：XTH、XTL的频率范围设定，需要根据外部晶振决定，
///< 注意3：本驱动默认宏定义：SYSTEM_XTH=32MHz,SYSTEM_XTL=32768Hz,如使用其它外部晶振，必须修改这两个宏定义的值。
en_result_t Sysctrl_ClkInit(stc_sysctrl_clk_cfg_t *pstcCfg);

///< 系统时钟去初始化API:恢复为上电默认状态->PCLK=HCLK=SystemClk=RCH4MHz
en_result_t Sysctrl_ClkDeInit(void);

///< 系统时钟模块的基本功能设置
///< 注意：使能需要使用的时钟源之前，必须优先设置目标内部时钟源的TRIM值或外部时钟源的频率范围
en_result_t Sysctrl_ClkSourceEnable(en_sysctrl_clk_source_t enSource, boolean_t bFlag);

///<外部晶振驱动配置：系统初始化Sysctrl_ClkInit()之后，可根据需要配置外部晶振的驱动能力，时钟初始化Sysctrl_ClkInit()默认为最大值;
en_result_t Sysctrl_XTHDriverCfg(en_sysctrl_xtal_driver_t enDriver);
en_result_t Sysctrl_XTLDriverCfg(en_sysctrl_xtl_amp_t enAmp, en_sysctrl_xtal_driver_t enDriver);

///<时钟稳定周期设置:系统初始化Sysctrl_ClkInit()之后，可根据需要配置时钟开启后的稳定之间，默认为最大值;
en_result_t Sysctrl_SetXTHStableTime(en_sysctrl_xth_cycle_t enCycle);
en_result_t Sysctrl_SetRCLStableTime(en_sysctrl_rcl_cycle_t enCycle);
en_result_t Sysctrl_SetXTLStableTime(en_sysctrl_xtl_cycle_t enCycle);
en_result_t Sysctrl_SetPLLStableTime(en_sysctrl_pll_cycle_t enCycle);

///<系统时钟源切换并更新系统时钟：如果需要在系统时钟初始化Sysctrl_ClkInit()之后切换主频时钟源，则使用该函数；
///< 时钟切换前后，必须根据目标频率值设置Flash读等待周期，可配置插入周期为0、1、2，
///< 注意!!!：当HCLK大于24MHz时，FLASH等待周期插入必须至少为1,否则程序运行可能产生未知错误
en_result_t Sysctrl_SysClkSwitch(en_sysctrl_clk_source_t enSource);

///< 时钟源频率设定：根据系统情况，单独设置不同时钟源的频率值;
///< 时钟频率设置前，必须根据目标频率值设置Flash读等待周期，可配置插入周期为0、1、2，
///< 其中XTL的时钟由外部晶振决定，无需设置。
en_result_t Sysctrl_SetRCHTrim(en_sysctrl_rch_freq_t enRCHFreq);
en_result_t Sysctrl_SetRCLTrim(en_sysctrl_rcl_freq_t enRCLFreq);
en_result_t Sysctrl_SetXTHFreq(en_sysctrl_xth_freq_t enXTHFreq);
en_result_t Sysctrl_SetPLLFreq(stc_sysctrl_pll_cfg_t *pstcPLLCfg);

///< 时钟分频设置:根据系统情况，单独设置HCLK、PCLK的分配值;
en_result_t Sysctrl_SetHCLKDiv(en_sysctrl_hclk_div_t enHCLKDiv);
en_result_t Sysctrl_SetPCLKDiv(en_sysctrl_pclk_div_t enPCLKDiv);

///< 时钟频率获取：根据系统需要，获取当前HCLK及PCLK的频率值
uint32_t Sysctrl_GetHClkFreq(void);
uint32_t Sysctrl_GetPClkFreq(void);

///< 外设门控开关/状态获取：用于控制外设模块的使能，使用该模块的功能之前，必须使能该模块的门控时钟；
en_result_t Sysctrl_SetPeripheralGate(en_sysctrl_peripheral_gate_t enPeripheral, boolean_t bFlag);
boolean_t   Sysctrl_GetPeripheralGate(en_sysctrl_peripheral_gate_t enPeripheral);

///< 系统功能配置：用于设置其他系统相关特殊功能；
en_result_t Sysctrl_SetFunc(en_sysctrl_func_t enFunc, boolean_t bFlag);

///< RTC高速时钟补偿:用于设置RTC高速时钟下的频率补偿
en_result_t Sysctrl_SetRTCAdjustClkFreq(en_sysctrl_rtc_adjust_t enRtcAdj);

//@} // Sysctrl Group

#ifdef __cplusplus
#endif

#endif /* __SYSCTRL_H__ */
/*******************************************************************************
 * EOF (not truncated)
 ******************************************************************************/


